package com.x.utils.http;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.util.Observable;

/**
 * <p>
 * Description:下载HTTP网络资源
 * </p>
 * 
 * @Author Chenkangming
 * @Date 2015-6-23
 * @version 1.0
 */
public class DownLoadUtil extends Observable {

	// Max size of download buffer.
	private int MAX_BUFFER_SIZE = 1024;

	// These are the status names.
	public static final String[] STATUSES = { "Downloading", "Paused", "Complete", "Cancelled", "Error" };

	// These are the status codes.
	public static final int DOWNLOADING = 0;
	public static final int PAUSED = 1;
	public static final int COMPLETE = 2;
	public static final int CANCELLED = 3;
	public static final int ERROR = 4;

	private URL url; // download URL
	private int size; // size of download in bytes
	private int downloaded; // number of bytes downloaded
	private int status; // current status of download
	private File path; // download file to save directory.
	private String fileName; // download file to change other name;default url
								// filename;

	private boolean isAuth; // Is the resources need Auth.default false
	private String userName; // login username.
	private String password; // login password.

	/**
	 * Constructor for DownUrlload.
	 * 
	 * @param url
	 *            下载url
	 * @param path
	 *            下载文件保存路径
	 * @param fileName
	 *            重命名文件名（为空则使用下载的文件名）
	 * @param downspeed
	 *            下载速度
	 * @throws MalformedURLException
	 */
	public DownLoadUtil(String url, String path, String fileName, int downspeed) throws MalformedURLException {
		if (url == null || url.equals("")) {
			throw new IllegalArgumentException("url: " + "文件下载路径不能为空");
		}
		this.url = new URL(url);
		size = -1;
		downloaded = 0;
		status = DOWNLOADING;
		MAX_BUFFER_SIZE = downspeed == 0 ? 1024 : downspeed;
		if (path==null || path.equals("")) {
			throw new IllegalArgumentException("path: " + "文件保存路径不能为空");
		}
		this.path = new File(path);
		this.fileName = fileName;

		// Begin the download.
		// download();
	}

	public boolean isAuth() {
		return isAuth;
	}

	public void setAuth(boolean isAuth) {
		this.isAuth = isAuth;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getUrl() {
		return url.toString();
	}

	public int getSize() {
		return size;
	}

	public float getProgress() {
		return ((float) downloaded / size) * 100;
	}

	public int getStatus() {
		return status;
	}

	public void pause() {
		status = PAUSED;
		stateChanged();
	}

	public String getPath() {
		return path.getPath();
	}

	public void setPath(String path) {
		this.path = new File(path);
	}

	// Resume this download.
	public void resume() {
		status = DOWNLOADING;
		stateChanged();
		download();
	}

	// Cancel this download.
	public void cancel() {
		status = CANCELLED;
		stateChanged();
	}

	// Mark this download as having an error.
	private void error() {
		status = ERROR;
		stateChanged();
	}

	// Start or resume downloading.
	private void download() {
		// Thread thread = new Thread(this);
		// thread.start();
		run();
	}

	// Get file name portion of URL.
	private String getFileName(URL url) {
		String fileName = url.getFile();
		return fileName.substring(fileName.lastIndexOf("/") + 1);
	}

	private void stateChanged() {
		setChanged();
		notifyObservers();
	}

	// Download file.
	public void run() {
		RandomAccessFile file = null;
		InputStream stream = null;
		HttpURLConnection connection = null;
		try {
			// Open Connection to URL.
			connection = (HttpURLConnection) url.openConnection();

			if (isAuth) {
				Authenticator.setDefault(new Authenticator() {
					protected PasswordAuthentication getPasswordAuthentication() {
						return new PasswordAuthentication(userName, password.toCharArray());
					}
				});
			}

			// Specify what portion of file to download.
			connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
			// Connect to server.
			connection.connect();

			// Make sure response code is in the 200 range.
			if (connection.getResponseCode() / 100 != 2) {
				error();
			}

			// Check for valid content length.
			int contentLength = connection.getContentLength();
			if (contentLength < 1) {
				error();
			}

			// Set the size for this download if it has not been already set.
			if (size == -1) {
				size = contentLength;
				stateChanged();
			}

			if (!path.isDirectory()) {
				path.mkdirs();
			}

			// Open file and seek to the end of it.
			if (fileName != null) {
				File file1 = new File(getPath() + File.separator + fileName);
				file1.deleteOnExit();// 如果文件存在，则执行删除

				file = new RandomAccessFile(new File(getPath() + File.separator + fileName), "rw");
			} else {
				file = new RandomAccessFile(new File(getPath() + File.separator + getFileName(url)), "rw");
			}
			file.seek(downloaded);

			stream = connection.getInputStream();
			while (status == DOWNLOADING) {
				// Size buffer according to how much of the file is left to
				// download.
				byte buffer[];
				if (size - downloaded > MAX_BUFFER_SIZE) {
					buffer = new byte[MAX_BUFFER_SIZE];
				} else {
					buffer = new byte[size - downloaded];
				}

				// Read from server into buffer.
				int read = stream.read(buffer);
				if (read == -1) {
					break;
				}

				// Write buffer to file.
				file.write(buffer, 0, read);
				downloaded += read;
				stateChanged();
			}

			// Change status to complete if this point was reached because
			// downloading has finish.
			if (status == DOWNLOADING) {
				status = COMPLETE;
				stateChanged();
			}
		} catch (IOException e) {
			error();
			throw new IllegalArgumentException(e);
		} finally {
			// Close file.
			if (file != null) {
				try {
					file.close();
				} catch (IOException e) {
					throw new IllegalArgumentException(e);
				}
			}

			// Close connection to server.
			if (stream != null) {
				try {
					stream.close();
				} catch (IOException e) {
					throw new IllegalArgumentException(e);
				}
			}

			if (connection != null) {
				connection.disconnect();
			}
		}
	}

	public static void main(String[] args) throws MalformedURLException, InterruptedException {
		// new Thread() {
		// @Override
		// public void run() {
		try {
			DownLoadUtil d = new DownLoadUtil("http://100.84.42.16:12005/test/x2_act_2015092211.log", "d://", "1_x2_test.log", 200);
			System.out.println("文件大小：" + d.getSize());
			d.run();
			// if (d.status == 2) {
			// System.out.println("下载完成");
			// }
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	// }.start();

	// new Thread() {
	// @Override
	// public void run() {
	// try {
	// DownLoadUtil d = new
	// DownLoadUtil("http://100.84.42.16:12005/test/info.log", "d://",
	// "2_x2_info.log", 200);
	// d.run();
	// if (d.status == 2) {
	// System.out.println("下载完成");
	// }
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// }
	// }.start();
	//
	// Thread.sleep(3600*10000);
	// }
}
